#ifndef IMI_MEDIA_COMMON
#define IMI_MEDIA_COMMON

#pragma pack(push,1)

#define IMI_NALU_MAX 32
#define IMI_H264_NALU_TYPE(x) (x & 0x1F)
#define IMI_H265_NALU_TYPE(x) ((x & 0x7E) >> 1);

typedef struct imi_nalu_array_s {
    unsigned char* _src_data;
    unsigned int _src_len;
    unsigned int _nalu_num;
    unsigned char* _nalu_index[IMI_NALU_MAX];
    unsigned int _nalu_len[IMI_NALU_MAX];
    unsigned int _nalu_startcode[IMI_NALU_MAX];
} imi_nalu_array_s, *imi_nalu_array_t;

static const unsigned char imi_nalu_startcode4[4] = {0x0, 0x0, 0x0, 0x01};
static const unsigned char imi_nalu_startcode3[3] = {0x0, 0x0, 0x01};

static imi_nalu_array_t imi_get_nalu_array(unsigned char* data, unsigned int data_len) {
    unsigned char* dataEnd = data;
    imi_nalu_array_t nalu_array = (imi_nalu_array_t)malloc(sizeof(imi_nalu_array_s));
    memset(nalu_array, 0, sizeof(imi_nalu_array_s));
    nalu_array->_src_data = data;
    nalu_array->_src_len = data_len;
    while (dataEnd != data + data_len) {
        if ((*dataEnd) == 0x01) {
            int nalu_startcode_size = 0;
            if (memcmp(dataEnd-3, imi_nalu_startcode4, 4) == 0) {
                nalu_startcode_size = sizeof(imi_nalu_startcode4);
            } else if (memcmp(dataEnd-2, imi_nalu_startcode3, 3) == 0) {
                nalu_startcode_size = sizeof(imi_nalu_startcode3);
            } else {
                //do nothing
            }
            if (nalu_startcode_size != 0) {
                nalu_array->_nalu_index[nalu_array->_nalu_num] = dataEnd - nalu_startcode_size + 1;
                nalu_array->_nalu_startcode[nalu_array->_nalu_num] = nalu_startcode_size;
                if (nalu_array->_nalu_num != 0) {
                    nalu_array->_nalu_len[nalu_array->_nalu_num-1] = nalu_array->_nalu_index[nalu_array->_nalu_num] - nalu_array->_nalu_index[nalu_array->_nalu_num-1];
                }
                nalu_array->_nalu_num++;
            }
        }
        dataEnd++;
    }
    if (nalu_array->_nalu_num != 0) {
        nalu_array->_nalu_len[nalu_array->_nalu_num-1] = dataEnd - nalu_array->_nalu_index[nalu_array->_nalu_num-1];
        return nalu_array;
    }
    free(nalu_array);
    return NULL;
}

static void imi_free_nalu_array(imi_nalu_array_t nalu_array) {
    free(nalu_array);
    nalu_array = NULL;
}

#pragma pack(pop)

#endif
